home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / pctuto.zip / DISK4.EXE / lha / CHAP20.DOC < prev    next >
Text File  |  1990-07-25  |  13KB  |  447 lines

  1.  
  2.  
  3.  
  4.                                                                            212
  5.  
  6.                             CHAPTER 20 - CONTROL STRUCTURES
  7.  
  8.  
  9.  
  10.              Control structures are things like 'for', 'do', 'while' and 'if'
  11.              that you have in high level languages. It is possible to do these
  12.              things in assembler language if you want. They are included here
  13.              so if you ever want to use them at this level, you will have a
  14.              template on how to set them up. 
  15.  
  16.              All the examples will use integers only. If you have real
  17.              numbers:
  18.  
  19.                  if ( variable < 3.891 ) 
  20.                       x = 4 * y ;
  21.  
  22.              it is too difficult to implement on the 8086. Of course, if you
  23.              have an 8087, it's a piece of cake.
  24.  
  25.  
  26.              IF
  27.  
  28.              IF is the easiest and it will illustrate how we are going to set
  29.              up our labels. Let's take that first example. Since it is a waste
  30.              of space to define variables over and over, we will assume that
  31.              all variables are words, not bytes. The examples will all be
  32.              written in C.
  33.  
  34.                  if (variable < 7)
  35.                  {
  36.                       x = 4 + y ;
  37.                  }
  38.  
  39.              The assembler code looks like this:
  40.  
  41.              if1: ;----------------
  42.                  cmp  variable, 7
  43.                  jge  end_if1
  44.  
  45.                  mov  x, 4
  46.                  mov  ax, y
  47.                  add  x, ax
  48.              end_if1: ;----------------
  49.  
  50.              All labels will look like variations of this. The control words
  51.              will be the labels.{1}  They will have a unique number for each
  52.              block so you can write as many different blocks as you want; the
  53.              label that signals the end of the block will be the word 'end_'
  54.              followed by the control word. The semicolon with the line is a
  55.              ____________________
  56.  
  57.                 1. The words 'if' and 'endif' are Microsoft macro directives,
  58.              so if you use them without a tag number, you will get some
  59.              bizarre code indeed. 
  60.  
  61.              ______________________
  62.  
  63.              The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson
  64.  
  65.  
  66.  
  67.  
  68.              Chapter 20 - Control Structures                               213
  69.              _______________________________
  70.  
  71.              comment, and it is used for visual separation. 
  72.  
  73.              By using a different number each time, you may nest as deeply as
  74.              you want, though the code will be pretty unreadable:
  75.  
  76.                  if   (variable < 7 )
  77.                  {
  78.                       if ( x > 9 )
  79.                       {
  80.                            if ( z == 0 )
  81.                            {
  82.                                 y = 12 ;
  83.                            }
  84.                            q = 5 ;
  85.                       }
  86.                       r = 7 ;
  87.                  }
  88.  
  89.              becomes:
  90.  
  91.              if1: ;---------------
  92.                  cmp  variable, 7
  93.                  jge  end_if1
  94.  
  95.              if2: ;---------------
  96.                  cmp  x, 9
  97.                  jle  end_if2
  98.  
  99.              if3: ;---------------
  100.                  cmp  z, 0
  101.                  jne  end_if3
  102.  
  103.                  mov  y, 12
  104.              end_if3: ;-----------
  105.                  mov  q, 5
  106.              end_if2: ;-----------
  107.                  mov  r, 7
  108.              end_if1: ;-----------
  109.  
  110.  
  111.              With the Microsoft assembler, you don't need to have the labels
  112.              start at the beginning of the line, but they MUST be the first
  113.              thing on the line. You can indent them:
  114.  
  115.              if1: ; --------------
  116.                  cmp  variable, 7
  117.                  jge  end_if1
  118.  
  119.                  if2: ;-------------
  120.                       cmp  x, 9
  121.                       jle  end_if2
  122.  
  123.                       if3: ;------------
  124.                            cmp  z, 0
  125.                            jne  end_if3
  126.  
  127.                            mov  y, 12
  128.  
  129.  
  130.  
  131.  
  132.              The PC Assembler Tutor                                        214
  133.              ______________________
  134.  
  135.                       end_if3: ;--------
  136.                       mov  q, 5
  137.                  end_if2: ;---------
  138.                  mov  r, 7
  139.              end_if1: ;---------
  140.  
  141.              You will notice that they are all compares and jumps using
  142.              reverse logic. If the condition is NOT true, then we jump. If it
  143.              is true, we just go on. What about IF ELSE? It looks almost the
  144.              same.
  145.  
  146.                  if ( j < 12 )
  147.                  {
  148.                       y = 19 ;
  149.                  }
  150.                  else
  151.                  {
  152.                       z = 25 ;
  153.                  }
  154.  
  155.              We get:
  156.  
  157.              if16: ;----------------
  158.  
  159.                  cmp  j, 12
  160.                  jge  else16
  161.  
  162.                  mov  y, 19
  163.                  jmp  end_if16
  164.  
  165.              else16:
  166.                  mov  z, 25
  167.                   end_else16:
  168.              end_if16: ;---------------
  169.  
  170.              We jump to another part inside the block, and throw in a JMP
  171.              after the IF part.
  172.  
  173.  
  174.              WHILE
  175.  
  176.              WHILE is the same as IF except that at the end of the block, we
  177.              jump back to the beginning.
  178.  
  179.                  while ( j < 20 )
  180.                  {
  181.                       j = j + 1 ;
  182.                  }
  183.  
  184.              while25: ;------------
  185.                  cmp  j, 20
  186.                  jge  end_while25
  187.  
  188.                  inc  j
  189.                  jmp  while25
  190.              end_while25: ;-----------
  191.  
  192.  
  193.  
  194.  
  195.  
  196.              Chapter 20 - Control Structures                               215
  197.              _______________________________
  198.  
  199.  
  200.              DO WHILE
  201.  
  202.              DO WHILE always goes through the code once. The decision process
  203.              is at the end.
  204.  
  205.                  do
  206.                  {
  207.                       k = k + 7 ;
  208.                  } while (k < 0) ;
  209.  
  210.  
  211.              do_while74: ;------------
  212.                  add  k, 7
  213.  
  214.                  cmp  k, 0
  215.                  jl   do_while74
  216.              end_do_while74: ;------------
  217.  
  218.              Notice that here the jump is a positive decision. If the
  219.              condition is fulfilled, we jump back to the start, otherwise we
  220.              fall through. What do you do with 'break' and 'continue'? {2}
  221.              Let's put them in:
  222.  
  223.                  do
  224.                  {
  225.                       k = k + 7 ;
  226.                       if ( y < 9 )
  227.                       {
  228.                            continue ;
  229.                       }
  230.                       j = j - 6 ;
  231.                       if ( z == 5 )
  232.                       {
  233.                            break ;
  234.                       }
  235.                       y = y * 2 ;
  236.                  } while ( j < 17) ;
  237.  
  238.              In assembler language, this becomes:
  239.  
  240.              do_while143: ;----------
  241.                  add  k, 7
  242.  
  243.                  if144: ;-----------
  244.                       cmp  y, 9
  245.                       jge  end_if144
  246.  
  247.                       jmp  continue143
  248.                  end_if144: ;-----------
  249.  
  250.                  sub  j, 6
  251.              ____________________
  252.  
  253.                 2. For those of you who are not C people, BREAK breaks you out
  254.              of the innermost loop. CONTINUE skips all the code till the end
  255.              of the loop.
  256.  
  257.  
  258.  
  259.  
  260.              The PC Assembler Tutor                                        216
  261.              ______________________
  262.  
  263.  
  264.                  if145: ;-----------
  265.                       cmp  z, 5
  266.                       jne  end_if145
  267.  
  268.                       jmp  break143
  269.                  end_if145: ;-----------
  270.  
  271.                  sal  y, 1           ; shift left 1 = multiply by 2
  272.              continue143:
  273.                  cmp  j, 17
  274.                  jl   do_while143
  275.              end_do_while143:
  276.              break143:
  277.  
  278.              In DO WHILE, CONTINUE is the label just before the decision
  279.              process. BREAK is always the first label after the block. We can
  280.              just use the label that marks the end of our block for the break.
  281.              Instead of:
  282.  
  283.                  jmp  break143
  284.  
  285.              we can have:
  286.  
  287.                  jmp  end_do_while143
  288.  
  289.              From now on, we'll put in the continue and break, even if they
  290.              aren't used. Once you are used to it, you can drop the break
  291.              label and use the end of block label. Going back to the WHILE
  292.              statement, we have:
  293.  
  294.              while25: ;------------
  295.                  cmp  j, 20
  296.                  jge  end_while25
  297.  
  298.                  inc  j
  299.              continue25:
  300.                  jmp  while25
  301.              end_while25: ;-----------
  302.              break25:
  303.  
  304.  
  305.  
  306.              FOR
  307.  
  308.              The FOR statement in C is more sophisticated than in other
  309.              languages, but we will keep the example simple. It has 3 parts:
  310.  
  311.                  for ( i = 11 ; i < 20 ; i = i + 1 )
  312.  
  313.              can be looked at as:
  314.  
  315.                  for ( initialize ; test ; update )
  316.  
  317.              The reason that it is sophisticated is that it can have any
  318.              number of things in the first and third parts.
  319.  
  320.  
  321.  
  322.  
  323.  
  324.              Chapter 20 - Control Structures                               217
  325.              _______________________________
  326.  
  327.                  for ( i = 11, j = 27  z = 4 ; i < 20 ; k = k + 1, j = j/2)
  328.  
  329.              is legitimate. Therefore we need to set aside a block for the
  330.              initialize part, a block for the test part, and a block for the
  331.              update part. One question is whether we want the initialization
  332.              inside the FOR label. I'm not doing it, but it is a possibility.
  333.              Here's the C code.
  334.  
  335.                  for ( i = 11 ; i < 20 ; i = i + 1 )
  336.                  {
  337.                       k = k + 9
  338.                  }
  339.  
  340.              And its corresponding assembler code:
  341.  
  342.              init217: ;---------------
  343.  
  344.                  mov  i, 11
  345.                  end_init217: ;------
  346.              for217: ; ---------------
  347.              test217:
  348.                  cmp  i, 20
  349.                  jge  end_for217
  350.                  end_test217: ;-----
  351.  
  352.                  add  k,9
  353.  
  354.              continue217:
  355.              update217:
  356.                  inc  i
  357.                  end_update217: ; ----
  358.                  jmp  test217
  359.              end_for217: ;-------------
  360.              break217:
  361.  
  362.              My that's a lot of labels. In this example we would get rid of
  363.              most of them because there is so little code, but if the block
  364.              contained a lot of code they would be a help, not a hindrance.
  365.              Remember, a label generates no code, so this makes no difference
  366.              in the size of the object file. Some of the labels which are not
  367.              targets of jumps could be made into comments. 
  368.  
  369.                  end_update217: ;----
  370.  
  371.              can become:
  372.  
  373.                  ; end_update217 ----
  374.  
  375.              Whichever way looks better to you. Using comments instead of
  376.              labels gives you a slightly faster compile time. Just make sure
  377.              you don't change one that IS a target of a jump.
  378.  
  379.  
  380.              SWITCH
  381.  
  382.              Finally there is the switch statement. If you don't know what it
  383.              is, skip this section because it will probably be confusing.
  384.  
  385.  
  386.  
  387.  
  388.              The PC Assembler Tutor                                        218
  389.              ______________________
  390.  
  391.  
  392.                  switch ( k )
  393.                  {
  394.                            case 'A':      x = x + 9 ;
  395.                                           break ;
  396.  
  397.                            case '&':      y = y * 2 ;
  398.                                           break ;
  399.  
  400.                            case 'j':      z = z - 7 ;
  401.                                           break ;
  402.                  }
  403.  
  404.              We get the following:
  405.  
  406.              switch82: ;-----------------
  407.  
  408.                  cmp  k, 'A'
  409.                  jne  test82_2
  410.                  jmp  case82_1
  411.              test82_2
  412.                  cmp  k, '&'
  413.                  jne  test82_3
  414.                  jmp  case82_2
  415.              test82_3
  416.                  cmp  k, 'j'
  417.                  jne  end_test82
  418.                  jmp  case82_3
  419.              end_test82:
  420.                  jmp  deafult82
  421.                  ; ----------
  422.  
  423.              case82_1:
  424.                  add  x, 9
  425.                  jmp  break82
  426.  
  427.              case82_2:
  428.                  sal  y, 1           ; multiply by 2
  429.                  jmp  break82
  430.  
  431.              case82_3:
  432.                  sub  z, 7
  433.                  jmp  break82
  434.  
  435.              default82:
  436.                  jmp  break82
  437.  
  438.              end_switch82: ;------------
  439.              break82:
  440.  
  441.              It may look like there are unnecessary jumps at the beginning,
  442.              but it is likely that in a real program some of the case
  443.              statements would be more than +127 bytes away from the
  444.              conditional jumps, so you need JMP, which can go anywhere in the
  445.              segment.
  446.  
  447.